1. /* sxfxsdiv.cpp by K.Tsuru */
  2. // function ID = 510 BRADIX
  3. /*****************************************************
  4. SDecimal class
  5. Provides the division of SDecimal by a short integer.
  6. result = m/x, x <= ULONG_MAX/BRADIX
  7. ******************************************************/
  8. #ifndef SN_H
  9. #include "sn.h"
  10. #endif
  11. static const char* func = "XsDiv";
  12. void XsDiv(const SDecimal& m, ulong x, SDecimal& result){
  13. if(x > m.SlOpMaxValue()) m.SetError(m.OUT_OF_RANGE, func, 510);
  14. if(!x) m.SetError(m.DIVIDED_BY_ZERO, func, 510);
  15. if(!m.Sign()){ result.SetZero(); return; }
  16. if(x == 1){
  17. result = m; return;
  18. }
  19. if( result.figure.size() != m.figure.size() ) m.SetError(m.SYNTAX_ERR, func, 510);
  20. uint i, rsz = result.Size();
  21. /*
  22. Considering the case &m == &result pay attention to not destroy the content of "m"
  23. via "result".
  24. For the fast access to figure[] do it via the first address of "elements".In the
  25. calculation of pi in 65,528 figures it is 40% faster than the "result.figure[]"
  26. version.
  27. */
  28. fType* rv = result.figure.Elements();
  29. const fType* mv = m.ReadFigures();
  30. #ifndef NDEBUG
  31. result.figure[rsz-1]; m.figure(rsz-1);
  32. #endif
  33. //When the figures of "m" is small it maybe get a factor by a few aditional figures.
  34. //For example 1/256.
  35. uint rt = m.aTail, rh = rsz -1, k = min(m.aHead + 4u, rsz);
  36. #ifndef NDEBUG
  37. result.figure[k-1]; m.figure(k-1);
  38. #endif
  39. ulong t = 0;
  40. #if 1 // mv[] version
  41. for( i = rt; i < k; i++) {
  42. t = (t << BRADIX_BITS) + mv[i];
  43. //Because mv[i] < BRADIX this statement can be replaced by
  44. //"t = (t << BRADIX_BITS) | mv[i];" but the speed is the same.
  45. rv[i] = fType(t/x);
  46. t = t - rv[i]*x; //This is faster than t = t%x;.
  47. }
  48. #else // *mv version Its speed is the same as mv[] version.
  49. //It would be optimized mv[] ---> *mv by Turbo C++.
  50. mv += rt; rv += rt;
  51. for( i = rt; i < k; i++) {
  52. t = (t << BRADIX_BITS) + *mv;
  53. *rv = fType(t/x);
  54. t = t - (*rv)*x;
  55. mv++; rv++;
  56. }
  57. rv = result.figure.Elements(); mv = m.ReadFigures();
  58. #endif
  59. if(t){//Maybe infinite decimal. mv[i] = 0 <-- This avoids the overhead caused by reading mv[].
  60. for( ; i < rsz; i++){ //Because it is a rare case that the remainder becomes zero,
  61. //it does not add the condition t == 0.
  62. t = (t << BRADIX_BITS);
  63. rv[i] = fType(t/x);
  64. t = t - rv[i]*x;
  65. }
  66. rh = rsz -1;
  67. //The residual part is filled by zeros.
  68. } else if(result.aHead >= i){ //finite decimal
  69. result.figure.clear(i); rh = i-1;
  70. }
  71. if(result.aTail < rt) result.figure.clear(result.aTail, rt-1);
  72. //Ut check the figure positions.
  73. while( (rt < rsz) && !rv[rt]) rt++; //The figures decreases?
  74. if( (rt == rsz) && !rv[rt-1] ){ //It becomes zero.
  75. result.aTail = result.aHead = 0; result.SetSign(0);
  76. } else { //Almost the lowest figure is not zero.
  77. result.aTail = rt;
  78. k = rh;
  79. while(k && !rv[k]) k--;
  80. result.aHead = k;
  81. result.SetSign(m.Sign());
  82. }
  83. }

sxfxsdiv.cpp : last modifiled at 2017/03/13 14:32:02(2,932 bytes)
created at 2015/12/22 16:09:56
The creation time of this html file is 2017/10/27 15:45:59 (Fri Oct 27 15:45:59 2017).